package com.lipuwater.agent.ble.control;

import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.widget.Toast;

import com.lipuwater.agent.ble.DeviceNotice;
import com.lipuwater.agent.ble.DeviceWrite;
import com.lipuwater.agent.ble.command.DeviceCommand10;
import com.lipuwater.agent.ble.command.DeviceCommand15;
import com.lipuwater.agent.ble.command.DeviceCommand30;
import com.lipuwater.agent.ble.eventbus.DeviceBindingEvent;
import com.lipuwater.agent.ble.http.DeviceActivateHttp;
import com.lipuwater.agent.ble.listener.NoticeListener;
import com.lipuwater.agent.ble.utils.ByteParsing;
import com.lipuwater.agent.ble.utils.ByteUtils;
import com.lipuwater.agent.ui.dialog.LoadingDialog;
import com.lipuwater.agent.utils.link.CompleteInterface;
import com.lipuwater.agent.utils.link.ErrorInterface;
import com.lipuwater.agent.utils.link.LinkCallTask;
import com.lipuwater.agent.utils.link.NextInterface;
import com.ismartlib.utils.L;

import de.greenrobot.event.EventBus;


/**
 * 　　　┏┓　　　┏┓
 * 　　┏┛┻━━━┛┻┓
 * 　　┃　　　　　　　┃
 * 　　┃　　　━　　　┃
 * 　　┃　┳┛　┗┳　┃
 * 　　┃　　　　　　　┃
 * 　　┃　　　┻　　　┃
 * 　　┃　　　　　　　┃
 * 　　┗━┓　　　┏━┛
 * 　　　　┃　　　┃神兽保佑
 * 　　　　┃　　　┃永无BUG！
 * 　　　　┃　　　┗━━━┓
 * 　　　　┃　　　　　　　┣┓
 * 　　　　┃　　　　　　　┏┛
 * 　　　　┗┓┓┏━┳┓┏┛
 * 　　　　　┃┫┫　┃┫┫
 * 　　　　　┗┻┛　┗┻┛
 * ━━━━━━神兽出没━━━━━━
 * Created by  Administrator  on 2016/12/20.
 * Email:924686754@qq.com
 * 设备激活控制器，处理未激活设备的流程（激活包含绑定）
 */
public class DeviceActivateControl implements DeviceActivateHttp.CallBack, NoticeListener {

    private Context mContext;
    private String token;
    /*
     * 设备操作对象
     */
    private DeviceWrite mDeviceWrite;
    private DeviceNotice mDeviceNotice;
    /**
     * 当前执行步骤
     * 请求设备协议版本->请求设备MCU（des加密）->请求设备时间标识->
     * 请求服务器主板编码（des加密）、请求服务器剩余时间充值指令（sha512加密+des加密）->
     * 请求设备状态参数等->是否成功
     */

    /**
     * 设备属性
     */
    private String mMac = "设备MAC地址";
    private String mProductCode = "设备产品编码";
    private String mDeviceName = "设备名称";

    private String mProtocolVersion = "设备协议版本";
    private String mDeviceMCU = "设备MCU序列号";
    private String mDeviceTime = "设备时间标识";

    private int mOrderId, mInstallType;

    private LoadingDialog mLoadingDialog = null;

    private Handler mHandler;
    private LinkCallTask mLinkCallTask = null;
    private DeviceActivateHttp mDeviceActivateHttp;

    private int mDeviceId = -1;

    public DeviceActivateControl(Context context, String token, String mac, String mProductCode, String deviceName, int orderId, int installType) {
        this.mContext = context;
        this.token = token;
        this.mMac = mac;
        this.mProductCode = mProductCode;
        this.mDeviceName = deviceName;
        this.mOrderId = orderId;
        this.mInstallType = installType;
        mDeviceNotice = new DeviceNotice();
        mDeviceNotice.Notify(mMac, this);
        mDeviceWrite = new DeviceWrite();
        mLoadingDialog = new LoadingDialog(mContext, "设备激活中...");
        mLoadingDialog.showDialog();
        mLinkCallTask = new LinkCallTask();
        steps();
        mHandler = new Handler();
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                mLinkCallTask.toStart();
            }
        }, 100);
    }

    @Override
    public void BleNotice(byte[] value, int receiveMsg, boolean losePackage) {
        if (!losePackage) {//没丢包
            switch (receiveMsg) {
                case 0x01:
                    mProtocolVersion = ByteUtils.toHexString(ByteParsing.getValidData30(value));
                    L.i("设备发送回来的协议版本:" + ByteUtils.toHexString(value));
                    mLinkCallTask.toNext();
                    break;
                case 0x02:
                    mDeviceMCU = ByteUtils.toHexString(ByteParsing.getValidData30(value));
                    L.i("设备发送回来的MCU序列号:" + ByteUtils.toHexString(value));
                    mLinkCallTask.toNext();
                    break;
                case 0x03:
                    mDeviceTime = ByteUtils.toHexString(ByteParsing.getValidData30(value));
                    L.i("设备发送回来的时间标识:" + ByteUtils.toHexString(value));
                    mLinkCallTask.toNext();
                    break;
                case 0x04:
                    if (ByteParsing.WriteMainCodeSuccess(value)) {
                        L.i("写入设备主板编码成功:" + ByteUtils.toHexString(value));
                        mLinkCallTask.toNext();
                    } else {
                        mLinkCallTask.toError("写入主板编码失败");
                    }
                    break;
                case 0x05:
                    mLinkCallTask.toNext(value);
                    break;
            }
        } else {
            mLinkCallTask.toRepeat();
        }
    }


    /**
     * 激活流程
     */
    private void steps() {
        mLinkCallTask.setNext(new NextInterface() {
            @Override
            public void onNext(Object object) {
                //读取设备协议版本
                String[] address = new String[]{"10000", "10001", "10002", "10003"};
                String data = DeviceCommand30.getCommand(address, "01");
                mDeviceWrite.writeData(data, mMac, null);
                L.i("读取设备协议版本:" + data);
            }
        }, new NextInterface() {
            @Override
            public void onNext(Object object) {
                //读取设备MCU
                String[] address = new String[]{"10004", "10005", "10006", "10007", "10008", "10009", "100010", "100011", "100012", "100013", "100014", "100015"};
                String data = DeviceCommand30.getCommand(address, "02");
                mDeviceWrite.writeData(data, mMac, null);
                L.i("读取设备MCU序列号:" + data);
            }
        }, new NextInterface() {
            @Override
            public void onNext(Object object) {
                //读取设备时间标识
                String[] address = new String[]{"11016", "11017", "11018", "11019"};
                String data = DeviceCommand30.getCommand(address, "03");
                mDeviceWrite.writeData(data, mMac, null);
                L.i("读取设备时间标识:" + data);
            }
        }, new NextInterface() {
            @Override
            public void onNext(Object object) {
                //提交数据到服务器并且获取设备主板编码
                mDeviceActivateHttp = new DeviceActivateHttp(mContext, token);
                mDeviceActivateHttp.setParams(mDeviceTime, mProtocolVersion, mDeviceMCU, mMac, mProductCode, mDeviceName);
                mDeviceActivateHttp.setCallBack(DeviceActivateControl.this).getMainCode();
            }
        }, new NextInterface() {
            @Override
            public void onNext(Object object) {
                //写入主板编码
                String mainCode = (String) object;
                String[] address = new String[]{"11000", "11001", "11002", "11003", "11004", "11005", "11006", "11007", "11008", "11009", "11010", "11011", "11012", "11013", "11014", "11015"};
                String data = DeviceCommand10.getCommand(address, mainCode, "04");
                mDeviceWrite.writeData(data, mMac, null);
                L.i("写入设备主板编码:" + data);
            }
        }, new NextInterface() {
            @Override
            public void onNext(Object object) {
                mDeviceActivateHttp.ConfirmActivate(mOrderId, mInstallType);
            }
        }, new NextInterface() {
            @Override
            public void onNext(Object object) {
                //获取服务器剩余天数
                mDeviceActivateHttp.getRechargedays();
            }
        }, new NextInterface() {
            @Override
            public void onNext(Object object) {
                //开始写入剩余时间指令
                String days = (String) object;
                if (days == null) {
                    //回到上一步
                    mLinkCallTask.toLast();
                    return;
                }
                L.i("服务器下发的剩余天数指令：" + days);
                String[] address = new String[]{"20000", "20001"};
                String data = DeviceCommand15.getCommand(address, days, "05");
                mDeviceWrite.writeData(data, mMac, null);
                L.i("写入设备剩余天数:" + data);
            }
        }, new NextInterface() {
            @Override
            public void onNext(Object object) {
                //判断写入剩余天数是否成功
                byte[] value = (byte[]) object;
                mDeviceNotice.unNotify();
                //不把剩余天数写入成功或者失败作为依据把写入主板成功作为依据
                if (ByteParsing.WriteDeciceHaveDaySuccess(value)) {
                    mLinkCallTask.toComplete();
                } else {
                    mLinkCallTask.toComplete();
                }
                L.i("设备返回充值天数状态:" + ByteUtils.toHexString(value));
            }
        }).setError(new ErrorInterface() {
            @Override
            public void onError(Object object) {
                String msg = (String) object;
                mDeviceActivateHttp.unCallBack();
                Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
                Activity activity = (Activity) mContext;
                activity.finish();
            }
        }).setComplete(new CompleteInterface() {
            @Override
            public void onComplete(Object object) {
                if (mLoadingDialog != null && mLoadingDialog.isShowing()) {
                    mLoadingDialog.dismiss();
                }
                mDeviceActivateHttp.unCallBack();
                EventBus.getDefault().post(new DeviceBindingEvent(mDeviceId, mMac, true));
            }
        });
    }

    public void unRegister() {
        mHandler.removeCallbacksAndMessages(null);
        mDeviceNotice.unNotify();//取消监听通知和回调
    }

    /**
     * ----------------------------------------------------------
     * ---------------------服务器返回的数据----------------------------
     * ----------------------------------------------------------
     */
    @Override
    public void onServiceData(String mainCode, String days, int deviceId, boolean confirmActivate) {
        if (confirmActivate) {
            mDeviceId = deviceId;
            mLinkCallTask.toNext();
        } else {

            if (mainCode != null && !mainCode.equals("")) {
                mLinkCallTask.toNext(mainCode);
            } else if (days != null && !days.equals("")) {
                mLinkCallTask.toNext(days);
            }
        }
    }


}
